package cn.liujianbo.example.pattern.proxy.dynamic_proxy;

import cn.liujianbo.example.pattern.proxy.static_proxy.AbstractSellTicket;
import cn.liujianbo.example.pattern.proxy.static_proxy.TrainStation;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @author 刘建波
 * @date 2022-03-03 21:29
 */
public class DynamicProxyFactory {

    public static AbstractSellTicket getProxy(AbstractSellTicket target) {
        /*
        newProxyInstance()方法参数说明：
        ClassLoader loader ： 类加载器，用于加载代理类，使用真实对象的类加载器即可
        Class<?>[] interfaces ： 真实对象所实现的接口，代理模式真实对象和代理对象实现相同的接口
        InvocationHandler h ： 代理对象的调用处理程序
        */
        return (AbstractSellTicket) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            /*
                InvocationHandler中invoke方法参数说明：
                proxy ： 代理对象
                method ： 对应于在代理对象上调用的接口方法的 Method 实例
                args ： 代理对象调用接口方法时传递的实际参数
            */
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("动态代理对象，代理卖票，收点儿手续费！");
                return method.invoke(target, args);
            }
        });
    }

    /**
     * 项目根目录生成反编译的代理类class
     * -Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
     * @param args
     */
    public static void main(String[] args) {
        TrainStation trainStation = new TrainStation();

        AbstractSellTicket proxy = getProxy(trainStation);
        proxy.sell();

    }
}
